package com.wxl.oss.controller;

import com.wxl.oss.utils.R;
import io.minio.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author wxl
 * @create 2021-10-31 19:53
 */
@RestController
@RequestMapping("/minio")
public class MinioController {

    private static final Logger LOGGER = LoggerFactory.getLogger(MinioController.class);

    @Value("${minio.endpoint}")
    private String ENDPOINT;

    @Value("${minio.bucketName}")
    private String BUCKET_NAME;

    @Value("${minio.accessKey}")
    private String ACCESS_KEY;

    @Value("${minio.secretKey}")
    private String SECRET_KEY;

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public R upload(@RequestParam("file") MultipartFile file) {
        try {
            //创建一个MinIO的Java客户端
            MinioClient minioClient = MinioClient.builder().endpoint(ENDPOINT).credentials(ACCESS_KEY,SECRET_KEY).build();

            boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(BUCKET_NAME).build());
            if (isExist) {
                LOGGER.info("存储桶已经存在！");
            } else {
                //创建存储桶并设置只读权限
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(BUCKET_NAME).build());

                // 可读
                StringBuilder policy = new StringBuilder();
                policy.append("{\n");
                policy.append("    \"Statement\": [\n");
                policy.append("        {\n");
                policy.append("            \"Action\": [\n");
                policy.append("                \"s3:GetBucketLocation\",\n");
                policy.append("                \"s3:ListBucket\"\n");
                policy.append("            ],\n");
                policy.append("            \"Effect\": \"Allow\",\n");
                policy.append("            \"Principal\": \"*\",\n");
                policy.append("            \"Resource\": \"arn:aws:s3:::*\"\n");
                policy.append("        },\n");
                policy.append("        {\n");
                policy.append("            \"Action\": \"s3:GetObject\",\n");
                policy.append("            \"Effect\": \"Allow\",\n");
                policy.append("            \"Principal\": \"*\",\n");
                policy.append("            \"Resource\": \"arn:aws:s3:::*\"\n");
                policy.append("        }\n");
                policy.append("    ],\n");
                policy.append("    \"Version\": \"2012-10-17\"\n");
                policy.append("}\n");

                minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(BUCKET_NAME).config(policy.toString()).build());
            }
            String filename = file.getOriginalFilename();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            // 设置存储对象名称  20211031/1.jpg  minio没有dir概念（差不多这个意思）
            String objectName = sdf.format(new Date()) + "/" + filename;
            // 使用putObject上传一个文件到存储桶中

            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(BUCKET_NAME)
                    .object(objectName)
                    .stream(file.getInputStream(), file.getSize(), -1)
                    .contentType(file.getContentType()).build());

            LOGGER.info("文件上传成功!");
            Map<String,String> data = new HashMap<>();
            data.put("fileName(upload file name)",filename);
            data.put("objectName(minio access name)",objectName);
            data.put("fileUrl",ENDPOINT + "/" + BUCKET_NAME + "/" + objectName);
            return R.ok().put("data",data);
        } catch (Exception e) {
            LOGGER.info("上传发生错误: {}！", e.getMessage());
        }
        return R.error();
    }


    @RequestMapping(value = "/delete", method = RequestMethod.POST)
    public R delete(@RequestParam("objectName") String objectName) {
        try {
            MinioClient minioClient = MinioClient.builder().endpoint(ENDPOINT).credentials(ACCESS_KEY,SECRET_KEY).build();
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(BUCKET_NAME).object(objectName).build());
            return R.ok();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return R.error();
    }
}